﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace Dabr.NET
{
    public enum MenuType
    {
        Top,
        Bottom
    }

    public partial class DabrPage : System.Web.UI.Page
    {
        protected Dictionary<string, MenuItem> MenuRegistry;
        Dictionary<string, MenuItem> visible_menu_entries;

        /// <summary>
        /// Initializes the menu system of the page.
        /// All menu-related operations MUST be invoked AFTER this method.
        /// </summary>
        protected void InitializeMenu()
        {
            MenuRegistry = new Dictionary<string, MenuItem>();
            visible_menu_entries = null;
        }

        #region Definitions of menu_register
        protected void RegisterMenu(string name, MenuItem a)
        {
            MenuRegistry.Add(name, a);
        }
        #endregion

        protected void ExecuteActiveHandler()
        {
            string q = Request.QueryString["q"];
            if (q == null) // The only non-string value possible in q
                q = ""; // Replace this with "" to prevent future mishaps.
            string query = q.Split('/')[0];
            MenuItem page;
            try
            {
                page = MenuRegistry[query];
            }
            catch (KeyNotFoundException) // Invalid request.
            {
                Response.StatusCode = 404; // Not found
                Response.StatusDescription = "Not Found";
                Response.Write("404 - Not Found.");
                Response.SuppressContent = true;
                Response.End();
                return;
            }
            if (page.Security)
                EnsureAuthenticated();

            // TODO: Invitation-only code and config.

            page.CallBack();
        }

        protected Dictionary<string, MenuItem> VisibleMenuItems
        {
            get
            {
                if(visible_menu_entries == null)
                {
                    visible_menu_entries = new Dictionary<string, MenuItem>();
                    foreach (KeyValuePair<string, MenuItem> i in MenuRegistry)
                    {
                        if (i.Value.Security && !IsAuthenticated)
                            continue;
                        else if (i.Value.Hidden)
                            continue;
                        else
                            visible_menu_entries.Add(i.Key, i.Value);
                    }
                }
                return visible_menu_entries;
            }
        }

        protected string DisplayMenu(MenuType type)
        {
            List<string> links = new List<string>();
            string title, url;
            MenuItem page;
            foreach (KeyValuePair<string, MenuItem> k in VisibleMenuItems)
            {
                url = k.Key;
                page = k.Value;
                if (url.Length > 0)
                    title = url;
                else
                {
                    title = "home";
                    url = BaseURL; // Should not be required, but some browsers are stupid.
                }
                if (type == MenuType.Bottom && page.AccessKey != '\0')
                    links.Add(String.Format("<a href=\"{0}\" accesskey=\"{1}\">{2}</a> {1}",
                        url, page.AccessKey, title));
                else
                    links.Add(String.Format("<a href=\"{0}\">{1}</a>", url, title));
            }
            if (IsAuthenticated)
                links.Insert(0, String.Format("<strong><a href=\"user/{0}\">{0}</a></strong>",
                    CurrentUsername));
            if (type == MenuType.Bottom)
                links.Add(String.Format("<a href=\"{0}\" accesskey=\"5\">refresh</a> 5",
                    Request.QueryString["q"] == null ? BaseURL : Request.QueryString["q"]));

            return String.Format("<div class=\"menu menu-{0}\">",
                type == MenuType.Top ? "top" : "bottom") + string.Join(" | ", links) + "</div>";
        }

        protected string DisplayTopMenu()
        {
            return DisplayMenu(MenuType.Top);
        }

        protected string DisplayBottomMenu()
        {
            return DisplayMenu(MenuType.Bottom);
        }
    }
}